import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import os
from datetime import datetime, timedelta

# 设置matplotlib显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号


def load_or_generate_forecast_data():
    """
    加载或生成中国平安股票的未来价格预测数据
    如果预测数据文件不存在，则生成模拟数据
    """
    forecast_file = '中国平安2318未来一个月预测.csv'

    if os.path.exists(forecast_file):
        print(f"正在加载预测数据: {forecast_file}")
        forecast_df = pd.read_csv(forecast_file)

        # 确保日期列是datetime类型
        forecast_df['日期'] = pd.to_datetime(forecast_df['日期'])

        # 检查是否包含必要列
        if '预测收盘价' not in forecast_df.columns:
            print("警告: 预测数据缺少'预测收盘价'列，将生成模拟数据")
            return generate_simulated_forecast()
        else:
            print(f"成功加载 {len(forecast_df)} 天的预测数据")
            return forecast_df

    else:
        print("预测数据文件不存在，将生成模拟数据")
        return generate_simulated_forecast()


def generate_simulated_forecast():
    """生成模拟的预测数据（如果问题一的预测结果不可用）"""
    print("正在生成模拟预测数据...")

    # 创建未来22个交易日的日期（2025-08-08 至 2025-09-05）
    start_date = datetime(2025, 8, 8)
    dates = []
    current_date = start_date
    count = 0

    while count < 22:
        if current_date.weekday() < 5:  # 跳过周末
            dates.append(current_date)
            count += 1
        current_date += timedelta(days=1)

    # 生成模拟的收盘价（基于问题一的预测趋势）
    # 从53.05元开始，先小幅下跌再回升
    prices = []
    base_price = 53.05

    for i in range(22):
        # 模拟先下跌后上涨的趋势
        if i < 5:
            # 前5天下跌
            price = base_price * (1 - 0.003 * i)
        elif i < 15:
            # 中间10天震荡上行
            price = base_price * (1 - 0.003 * 5 + 0.002 * (i - 5))
        else:
            # 最后7天继续上涨
            price = base_price * (1 - 0.003 * 5 + 0.002 * 10 + 0.0015 * (i - 15))

        # 添加随机波动
        price *= (1 + np.random.normal(0, 0.005))
        prices.append(round(price, 2))

    # 创建DataFrame
    forecast_df = pd.DataFrame({
        '日期': dates,
        '预测收盘价': prices
    })

    # 保存模拟数据
    forecast_df.to_csv('中国平安2318未来一个月预测.csv', index=False)
    print(f"已生成并保存 {len(forecast_df)} 天的模拟预测数据")

    return forecast_df


def estimate_high_low_from_historical():
    """
    基于历史数据估计最高价和最低价与收盘价的关系
    """
    historical_file = '中国平安2318历史数据.csv'

    if not os.path.exists(historical_file):
        print(f"警告: 历史数据文件 '{historical_file}' 不存在，将使用默认比例")
        return 1.015, 0.985  # 默认最高价比收盘价高1.5%，最低价比收盘价低1.5%

    print(f"正在分析历史数据: {historical_file}")
    df = pd.read_csv(historical_file)

    # 检查列名并重命名（如果需要）
    if '收盘' in df.columns and '高' in df.columns and '低' in df.columns:
        pass
    elif '收盘价' in df.columns and '最高价' in df.columns and '最低价' in df.columns:
        df = df.rename(columns={
            '收盘价': '收盘',
            '最高价': '高',
            '最低价': '低'
        })
    else:
        print("警告: 历史数据列名不匹配，将使用默认比例")
        return 1.015, 0.985

    # 计算最高价/收盘价和最低价/收盘价
    df['high_close_ratio'] = df['高'] / df['收盘']
    df['low_close_ratio'] = df['低'] / df['收盘']

    # 计算平均比例（排除异常值）
    high_ratio = df['high_close_ratio'].mean()
    low_ratio = df['low_close_ratio'].mean()

    print(f"历史数据分析结果:")
    print(f"  平均最高价/收盘价比例: {high_ratio:.4f}")
    print(f"  平均最低价/收盘价比例: {low_ratio:.4f}")

    return high_ratio, low_ratio


def calculate_scheme_prices(high, low):
    """计算两种交易方案的价格"""
    # 方案1: 买入价格=最低价，卖出价格=最高价
    buy_price1 = low
    sell_price1 = high

    # 方案2: 买入价格=最低价+0.25*(最高价-最低价)，卖出价格=最低价+0.75*(最高价-最低价)
    price_range = high - low
    buy_price2 = low + price_range * 0.25
    sell_price2 = low + price_range * 0.75

    return buy_price1, sell_price1, buy_price2, sell_price2


def calculate_risk_adjusted_position(current_price, predicted_change, volatility, max_position=0.9):
    """
    计算基于风险调整的仓位大小

    参数:
    current_price: 当前价格
    predicted_change: 预测价格变动百分比
    volatility: 价格波动率
    max_position: 最大仓位比例

    返回:
    仓位比例 (0-1)
    """
    # 基础仓位：与预测变动幅度成正比，但不超过最大仓位
    base_position = min(abs(predicted_change) * 10, max_position)

    # 波动率调整：波动率越高，仓位越小
    volatility_factor = 1 / (1 + volatility * 5)

    # 最终仓位
    position = base_position * volatility_factor

    return max(0.1, position)  # 最小仓位10%


def backtest_strategy(forecast_df, high_ratio, low_ratio, initial_cash=1000000, transaction_fee=0.0003):
    """
    回测交易策略

    参数:
    forecast_df: 预测数据DataFrame
    high_ratio: 最高价/收盘价比例
    low_ratio: 最低价/收盘价比例
    initial_cash: 初始资金
    transaction_fee: 交易费用比例

    返回:
    两种方案的交易记录和资产变化
    """
    print("\n" + "=" * 50)
    print("开始回测交易策略")
    print("=" * 50)

    # 估计每天的最高价和最低价
    forecast_df['最高价'] = forecast_df['预测收盘价'] * high_ratio
    forecast_df['最低价'] = forecast_df['预测收盘价'] * low_ratio

    # 计算预测价格变动（用于策略决策）
    forecast_df['预测变动'] = forecast_df['预测收盘价'].pct_change().shift(-1)

    # 计算波动率（使用历史波动率的估计值）
    volatility = 0.015  # 假设日波动率1.5%

    # 初始化变量
    cash1 = cash2 = initial_cash
    shares1 = shares2 = 0
    total_assets1 = []
    total_assets2 = []
    transactions1 = []
    transactions2 = []

    # 遍历每一天
    for i in range(len(forecast_df) - 1):
        current_date = forecast_df.iloc[i]['日期']
        current_close = forecast_df.iloc[i]['预测收盘价']
        next_close = forecast_df.iloc[i + 1]['预测收盘价']
        predicted_change = forecast_df.iloc[i]['预测变动']

        # 获取当天的最高价和最低价
        high = forecast_df.iloc[i]['最高价']
        low = forecast_df.iloc[i]['最低价']

        # 计算两种方案的交易价格
        buy_price1, sell_price1, buy_price2, sell_price2 = calculate_scheme_prices(high, low)

        # 记录总资产
        total_asset1 = cash1 + shares1 * current_close
        total_asset2 = cash2 + shares2 * current_close
        total_assets1.append((current_date, total_asset1))
        total_assets2.append((current_date, total_asset2))

        # 交易决策逻辑
        # 只有当预测变动超过交易成本时才交易
        min_profit_threshold = transaction_fee * 2.5  # 需要超过交易成本的2.5倍才交易

        # 方案1的决策
        if not pd.isna(predicted_change):
            if predicted_change > min_profit_threshold and cash1 > 0:
                # 计算基于风险调整的仓位
                position_size = calculate_risk_adjusted_position(
                    current_close, predicted_change, volatility
                )

                # 计算可以买入的数量
                max_shares = (cash1 * position_size) / (buy_price1 * (1 + transaction_fee))
                shares_to_buy = int(max_shares)

                if shares_to_buy > 0:
                    cost = shares_to_buy * buy_price1 * (1 + transaction_fee)
                    cash1 -= cost
                    shares1 += shares_to_buy
                    transactions1.append((
                        current_date, '买入', shares_to_buy,
                        buy_price1, cost, position_size
                    ))
                    print(
                        f"{current_date.date()}: 方案1 买入 {shares_to_buy} 股 @ {buy_price1:.2f}元 (仓位: {position_size:.1%})")

            elif predicted_change < -min_profit_threshold and shares1 > 0:
                # 卖出所有股票
                revenue = shares1 * sell_price1 * (1 - transaction_fee)
                cash1 += revenue
                transactions1.append((
                    current_date, '卖出', shares1,
                    sell_price1, revenue, 1.0
                ))
                print(f"{current_date.date()}: 方案1 卖出 {shares1} 股 @ {sell_price1:.2f}元")
                shares1 = 0

    # 处理最后一天（强制卖出）
    last_date = forecast_df.iloc[-1]['日期']
    last_close = forecast_df.iloc[-1]['预测收盘价']
    last_high = forecast_df.iloc[-1]['最高价']
    last_low = forecast_df.iloc[-1]['最低价']

    # 方案1最后一天卖出
    if shares1 > 0:
        _, sell_price1, _, _ = calculate_scheme_prices(last_high, last_low)
        revenue = shares1 * sell_price1 * (1 - transaction_fee)
        cash1 += revenue
        transactions1.append((
            last_date, '卖出(最后一天)', shares1,
            sell_price1, revenue, 1.0
        ))
        print(f"{last_date.date()}: 方案1 最后一天卖出 {shares1} 股 @ {sell_price1:.2f}元")
        shares1 = 0

    # 计算最终总资产
    final_asset1 = cash1
    total_assets1.append((last_date, final_asset1))

    print(f"\n方案1交易完成，最终资产: {final_asset1:,.2f}元")

    # 重置变量，测试方案2
    cash2 = initial_cash
    shares2 = 0

    # 遍历每一天（方案2）
    for i in range(len(forecast_df) - 1):
        current_date = forecast_df.iloc[i]['日期']
        current_close = forecast_df.iloc[i]['预测收盘价']
        next_close = forecast_df.iloc[i + 1]['预测收盘价']
        predicted_change = forecast_df.iloc[i]['预测变动']

        # 获取当天的最高价和最低价
        high = forecast_df.iloc[i]['最高价']
        low = forecast_df.iloc[i]['最低价']

        # 计算两种方案的交易价格
        buy_price1, sell_price1, buy_price2, sell_price2 = calculate_scheme_prices(high, low)

        # 记录总资产
        total_asset2 = cash2 + shares2 * current_close
        total_assets2.append((current_date, total_asset2))

        # 交易决策逻辑
        # 只有当预测变动超过交易成本时才交易
        min_profit_threshold = transaction_fee * 2.5  # 需要超过交易成本的2.5倍才交易

        if not pd.isna(predicted_change):
            if predicted_change > min_profit_threshold and cash2 > 0:
                # 计算基于风险调整的仓位
                position_size = calculate_risk_adjusted_position(
                    current_close, predicted_change, volatility
                )

                # 计算可以买入的数量
                max_shares = (cash2 * position_size) / (buy_price2 * (1 + transaction_fee))
                shares_to_buy = int(max_shares)

                if shares_to_buy > 0:
                    cost = shares_to_buy * buy_price2 * (1 + transaction_fee)
                    cash2 -= cost
                    shares2 += shares_to_buy
                    transactions2.append((
                        current_date, '买入', shares_to_buy,
                        buy_price2, cost, position_size
                    ))
                    print(
                        f"{current_date.date()}: 方案2 买入 {shares_to_buy} 股 @ {buy_price2:.2f}元 (仓位: {position_size:.1%})")

            elif predicted_change < -min_profit_threshold and shares2 > 0:
                # 卖出所有股票
                revenue = shares2 * sell_price2 * (1 - transaction_fee)
                cash2 += revenue
                transactions2.append((
                    current_date, '卖出', shares2,
                    sell_price2, revenue, 1.0
                ))
                print(f"{current_date.date()}: 方案2 卖出 {shares2} 股 @ {sell_price2:.2f}元")
                shares2 = 0

    # 方案2最后一天卖出
    if shares2 > 0:
        _, _, _, sell_price2 = calculate_scheme_prices(last_high, last_low)
        revenue = shares2 * sell_price2 * (1 - transaction_fee)
        cash2 += revenue
        transactions2.append((
            last_date, '卖出(最后一天)', shares2,
            sell_price2, revenue, 1.0
        ))
        print(f"{last_date.date()}: 方案2 最后一天卖出 {shares2} 股 @ {sell_price2:.2f}元")
        shares2 = 0

    # 计算最终总资产
    final_asset2 = cash2
    total_assets2.append((last_date, final_asset2))

    print(f"方案2交易完成，最终资产: {final_asset2:,.2f}元")

    return {
        'scheme1': {
            'transactions': transactions1,
            'total_assets': total_assets1,
            'final_cash': cash1,
            'final_shares': shares1,
            'final_asset': final_asset1
        },
        'scheme2': {
            'transactions': transactions2,
            'total_assets': total_assets2,
            'final_cash': cash2,
            'final_shares': shares2,
            'final_asset': final_asset2
        },
        'forecast_df': forecast_df
    }


def analyze_results(results, initial_cash=1000000):
    """分析交易结果"""
    scheme1 = results['scheme1']
    scheme2 = results['scheme2']
    forecast_df = results['forecast_df']

    # 计算收益率
    return1 = (scheme1['final_asset'] - initial_cash) / initial_cash
    return2 = (scheme2['final_asset'] - initial_cash) / initial_cash

    # 计算年化收益率（假设交易期为22个交易日）
    trading_days = len(forecast_df)
    annualized_return1 = return1 * (252 / trading_days)
    annualized_return2 = return2 * (252 / trading_days)

    # 计算最大回撤
    assets1 = np.array([item[1] for item in scheme1['total_assets']])
    assets2 = np.array([item[1] for item in scheme2['total_assets']])

    def calculate_max_drawdown(assets):
        peak = assets[0]
        max_drawdown = 0
        for asset in assets:
            if asset > peak:
                peak = asset
            drawdown = (peak - asset) / peak
            if drawdown > max_drawdown:
                max_drawdown = drawdown
        return max_drawdown

    max_drawdown1 = calculate_max_drawdown(assets1)
    max_drawdown2 = calculate_max_drawdown(assets2)

    # 计算夏普比率（假设无风险利率为2%年化）
    risk_free_rate = 0.02
    daily_risk_free = (1 + risk_free_rate) ** (1 / 252) - 1

    # 计算日收益率
    daily_returns1 = np.diff(assets1) / assets1[:-1]
    daily_returns2 = np.diff(assets2) / assets2[:-1]

    # 年化波动率
    annual_volatility1 = np.std(daily_returns1) * np.sqrt(252)
    annual_volatility2 = np.std(daily_returns2) * np.sqrt(252)

    # 夏普比率
    sharpe1 = (annualized_return1 - risk_free_rate) / annual_volatility1 if annual_volatility1 > 0 else 0
    sharpe2 = (annualized_return2 - risk_free_rate) / annual_volatility2 if annual_volatility2 > 0 else 0

    # 打印结果
    print("\n" + "=" * 50)
    print("交易策略分析结果")
    print("=" * 50)
    print(f"初始资金: {initial_cash:,.0f}元 ({initial_cash / 10000:.1f}万元)")
    print(
        f"交易周期: {trading_days}个交易日 ({forecast_df['日期'].min().date()} 至 {forecast_df['日期'].max().date()})")

    print("\n方案1（买入=最低价，卖出=最高价）:")
    print(f"最终资产: {scheme1['final_asset']:,.2f}元 ({scheme1['final_asset'] / 10000:.1f}万元)")
    print(f"总收益率: {return1 * 100:.2f}%")
    print(f"年化收益率: {annualized_return1 * 100:.2f}%")
    print(f"最大回撤: {max_drawdown1 * 100:.2f}%")
    print(f"年化波动率: {annual_volatility1 * 100:.2f}%")
    print(f"夏普比率: {sharpe1:.4f}")

    print("\n方案2（买入=1/4分位，卖出=3/4分位）:")
    print(f"最终资产: {scheme2['final_asset']:,.2f}元 ({scheme2['final_asset'] / 10000:.1f}万元)")
    print(f"总收益率: {return2 * 100:.2f}%")
    print(f"年化收益率: {annualized_return2 * 100:.2f}%")
    print(f"最大回撤: {max_drawdown2 * 100:.2f}%")
    print(f"年化波动率: {annual_volatility2 * 100:.2f}%")
    print(f"夏普比率: {sharpe2:.4f}")

    # 比较两种方案
    print("\n" + "=" * 50)
    print("方案比较")
    print("=" * 50)

    if return1 > return2:
        diff = scheme1['final_asset'] - scheme2['final_asset']
        print(f"方案1比方案2多赚: {diff:,.2f}元 ({diff / 10000:.1f}万元)")
        print("方案1表现更好")
    else:
        diff = scheme2['final_asset'] - scheme1['final_asset']
        print(f"方案2比方案1多赚: {diff:,.2f}元 ({diff / 10000:.1f}万元)")
        print("方案2表现更好")

    # 保存分析结果
    analysis_results = pd.DataFrame({
        '指标': ['总收益率', '年化收益率', '最大回撤', '年化波动率', '夏普比率'],
        '方案1': [
            f"{return1 * 100:.2f}%",
            f"{annualized_return1 * 100:.2f}%",
            f"{max_drawdown1 * 100:.2f}%",
            f"{annual_volatility1 * 100:.2f}%",
            f"{sharpe1:.4f}"
        ],
        '方案2': [
            f"{return2 * 100:.2f}%",
            f"{annualized_return2 * 100:.2f}%",
            f"{max_drawdown2 * 100:.2f}%",
            f"{annual_volatility2 * 100:.2f}%",
            f"{sharpe2:.4f}"
        ]
    })

    analysis_results.to_csv('strategy_analysis.csv', index=False)
    print("\n分析结果已保存到: strategy_analysis.csv")

    return {
        'return1': return1,
        'annualized_return1': annualized_return1,
        'max_drawdown1': max_drawdown1,
        'sharpe1': sharpe1,
        'return2': return2,
        'annualized_return2': annualized_return2,
        'max_drawdown2': max_drawdown2,
        'sharpe2': sharpe2
    }


def plot_results(forecast_df, results):
    """绘制结果图表"""
    scheme1 = results['scheme1']
    scheme2 = results['scheme2']

    # 1. 资产变化对比图
    plt.figure(figsize=(14, 7))

    # 方案1资产变化
    dates1 = [item[0] for item in scheme1['total_assets']]
    assets1 = [item[1] for item in scheme1['total_assets']]
    plt.plot(dates1, assets1, label='方案1（买入=最低价，卖出=最高价）', linewidth=2.5)

    # 方案2资产变化
    dates2 = [item[0] for item in scheme2['total_assets']]
    assets2 = [item[1] for item in scheme2['total_assets']]
    plt.plot(dates2, assets2, label='方案2（买入=1/4分位，卖出=3/4分位）', linewidth=2.5)

    # 初始资金线
    initial_cash = assets1[0]
    plt.axhline(y=initial_cash, color='r', linestyle='--', label='初始资金', linewidth=1.5)

    plt.title('资产变化对比', fontsize=16)
    plt.xlabel('日期', fontsize=12)
    plt.ylabel('总资产(元)', fontsize=12)
    plt.legend(fontsize=10)
    plt.grid(True, linestyle='--', alpha=0.7)

    # 设置日期格式
    plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
    plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=3))
    plt.gcf().autofmt_xdate()

    plt.tight_layout()
    plt.savefig('asset_comparison.png', dpi=300, bbox_inches='tight')
    print("已保存资产变化对比图: asset_comparison.png")

    # 2. 价格走势与交易点
    plt.figure(figsize=(14, 7))
    plt.plot(forecast_df['日期'], forecast_df['预测收盘价'],
             label='预测收盘价', linewidth=2.5, color='blue')

    # 标记方案1的买卖点
    buy_dates1 = []
    buy_prices1 = []
    sell_dates1 = []
    sell_prices1 = []

    for trans in scheme1['transactions']:
        date, action, _, price, _, _ = trans
        if action.startswith('买入'):
            buy_dates1.append(date)
            buy_prices1.append(price)
        elif action.startswith('卖出'):
            sell_dates1.append(date)
            sell_prices1.append(price)

    plt.scatter(buy_dates1, buy_prices1, color='green', marker='^', s=120,
                label='方案1买入点', zorder=5)
    plt.scatter(sell_dates1, sell_prices1, color='red', marker='v', s=120,
                label='方案1卖出点', zorder=5)

    # 标记方案2的买卖点
    buy_dates2 = []
    buy_prices2 = []
    sell_dates2 = []
    sell_prices2 = []

    for trans in scheme2['transactions']:
        date, action, _, price, _, _ = trans
        if action.startswith('买入'):
            buy_dates2.append(date)
            buy_prices2.append(price)
        elif action.startswith('卖出'):
            sell_dates2.append(date)
            sell_prices2.append(price)

    plt.scatter(buy_dates2, buy_prices2, color='cyan', marker='s', s=100,
                label='方案2买入点', zorder=5)
    plt.scatter(sell_dates2, sell_prices2, color='magenta', marker='x', s=100,
                label='方案2卖出点', zorder=5)

    # 添加最高价和最低价范围
    plt.fill_between(forecast_df['日期'], forecast_df['最低价'],
                     forecast_df['最高价'], color='gray', alpha=0.1,
                     label='价格波动区间')

    plt.title('价格走势与交易点', fontsize=16)
    plt.xlabel('日期', fontsize=12)
    plt.ylabel('价格(元)', fontsize=12)
    plt.legend(fontsize=10)
    plt.grid(True, linestyle='--', alpha=0.7)

    # 设置日期格式
    plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
    plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=3))
    plt.gcf().autofmt_xdate()

    plt.tight_layout()
    plt.savefig('price_trading_points.png', dpi=300, bbox_inches='tight')
    print("已保存价格走势与交易点图: price_trading_points.png")

    # 3. 交易记录表格
    plt.figure(figsize=(14, 8))
    plt.axis('off')

    # 方案1交易记录
    scheme1_transactions = pd.DataFrame(scheme1['transactions'],
                                        columns=['日期', '操作', '数量', '价格(元)', '金额(元)', '仓位比例'])
    scheme1_transactions['金额(元)'] = scheme1_transactions['金额(元)'].apply(lambda x: f"{x:,.2f}")
    scheme1_transactions['仓位比例'] = scheme1_transactions['仓位比例'].apply(lambda x: f"{x:.1%}")

    # 方案2交易记录
    scheme2_transactions = pd.DataFrame(scheme2['transactions'],
                                        columns=['日期', '操作', '数量', '价格(元)', '金额(元)', '仓位比例'])
    scheme2_transactions['金额(元)'] = scheme2_transactions['金额(元)'].apply(lambda x: f"{x:,.2f}")
    scheme2_transactions['仓位比例'] = scheme2_transactions['仓位比例'].apply(lambda x: f"{x:.1%}")

    # 创建表格
    ax = plt.gca()
    ax.axis('tight')
    ax.axis('off')

    # 表格标题
    plt.figtext(0.5, 0.95, "方案1交易记录（买入=最低价，卖出=最高价）",
                ha='center', fontsize=14, weight='bold')
    plt.figtext(0.5, 0.48, "方案2交易记录（买入=1/4分位，卖出=3/4分位）",
                ha='center', fontsize=14, weight='bold')

    # 方案1表格
    table1 = ax.table(cellText=scheme1_transactions.values,
                      colLabels=scheme1_transactions.columns,
                      cellLoc='center',
                      loc='upper center',
                      bbox=[0.1, 0.55, 0.8, 0.4])

    # 方案2表格
    table2 = ax.table(cellText=scheme2_transactions.values,
                      colLabels=scheme2_transactions.columns,
                      cellLoc='center',
                      loc='lower center',
                      bbox=[0.1, 0.05, 0.8, 0.4])

    # 设置表格样式
    table1.auto_set_font_size(False)
    table1.set_fontsize(9)
    table1.scale(1, 1.5)

    table2.auto_set_font_size(False)
    table2.set_fontsize(9)
    table2.scale(1, 1.5)

    plt.tight_layout()
    plt.savefig('trading_records.png', dpi=300, bbox_inches='tight')
    print("已保存交易记录表格: trading_records.png")

    plt.show()


def save_detailed_transactions(results):
    """保存详细的交易记录"""
    scheme1 = results['scheme1']
    scheme2 = results['scheme2']

    # 方案1交易记录
    scheme1_transactions = pd.DataFrame(scheme1['transactions'],
                                        columns=['日期', '操作', '数量', '价格', '金额', '仓位比例'])
    scheme1_transactions['金额'] = scheme1_transactions['金额'].apply(lambda x: f"{x:,.2f}")
    scheme1_transactions['仓位比例'] = scheme1_transactions['仓位比例'].apply(lambda x: f"{x:.1%}")
    scheme1_transactions.to_csv('scheme1_transactions.csv', index=False)

    # 方案2交易记录
    scheme2_transactions = pd.DataFrame(scheme2['transactions'],
                                        columns=['日期', '操作', '数量', '价格', '金额', '仓位比例'])
    scheme2_transactions['金额'] = scheme2_transactions['金额'].apply(lambda x: f"{x:,.2f}")
    scheme2_transactions['仓位比例'] = scheme2_transactions['仓位比例'].apply(lambda x: f"{x:.1%}")
    scheme2_transactions.to_csv('scheme2_transactions.csv', index=False)

    print("详细交易记录已保存:")
    print(f"  - 方案1: scheme1_transactions.csv ({len(scheme1_transactions)} 笔交易)")
    print(f"  - 方案2: scheme2_transactions.csv ({len(scheme2_transactions)} 笔交易)")


def main():
    """主函数"""
    print("=" * 60)
    print("中国平安股票投资策略设计")
    print(f"运行时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print("=" * 60)

    # 1. 加载或生成预测数据
    forecast_df = load_or_generate_forecast_data()

    # 2. 估计最高价和最低价与收盘价的关系
    high_ratio, low_ratio = estimate_high_low_from_historical()

    # 3. 回测交易策略
    results = backtest_strategy(forecast_df, high_ratio, low_ratio)

    # 4. 分析结果
    analysis = analyze_results(results)

    # 5. 保存详细交易记录
    save_detailed_transactions(results)

    # 6. 绘制结果图表
    print("\n" + "=" * 50)
    print("生成结果图表")
    print("=" * 50)
    plot_results(forecast_df, results)

    # 7. 生成策略报告
    print("\n" + "=" * 50)
    print("生成策略报告")
    print("=" * 50)

    report = f"""
# 中国平安股票投资策略报告

## 基本信息
- **股票代码**: 2318.HK (中国平安)
- **预测周期**: {forecast_df['日期'].min().date()} 至 {forecast_df['日期'].max().date()}
- **初始资金**: 1,000,000元 (100万元)
- **交易费用**: 0.03%
- **交易规则**: T+1

## 策略概述
本策略基于LSTM模型对中国平安股票未来价格的预测，采用动态仓位管理方法，根据预测价格变动幅度和市场波动率调整仓位大小。当预测价格上涨超过交易成本的2.5倍时买入，当预测价格下跌超过交易成本时卖出。

## 交易方案比较

### 方案1: 买入=最低价，卖出=最高价
- **最终资产**: {results['scheme1']['final_asset']:,.2f}元
- **总收益率**: {analysis['return1'] * 100:.2f}%
- **年化收益率**: {analysis['annualized_return1'] * 100:.2f}%
- **最大回撤**: {analysis['max_drawdown1'] * 100:.2f}%
- **夏普比率**: {analysis['sharpe1']:.4f}

### 方案2: 买入=1/4分位，卖出=3/4分位
- **最终资产**: {results['scheme2']['final_asset']:,.2f}元
- **总收益率**: {analysis['return2'] * 100:.2f}%
- **年化收益率**: {analysis['annualized_return2'] * 100:.2f}%
- **最大回撤**: {analysis['max_drawdown2'] * 100:.2f}%
- **夏普比率**: {analysis['sharpe2']:.4f}

## 策略结论
{'方案1' if analysis['return1'] > analysis['return2'] else '方案2'}表现更优，{'总收益率更高' if analysis['return1'] > analysis['return2'] else '风险调整后收益更高'}。
{'方案1的年化收益率比方案2高' + f"{(analysis['annualized_return1'] - analysis['annualized_return2']) * 100:.2f}%"
    if analysis['annualized_return1'] > analysis['annualized_return2']
    else '方案2的年化收益率比方案1高' + f"{(analysis['annualized_return2'] - analysis['annualized_return1']) * 100:.2f}%"}。

## 建议
基于回测结果，{'建议采用方案1' if analysis['return1'] > analysis['return2'] else '建议采用方案2'}进行交易。
{'该方案在保持较低风险的同时获得了较高的收益。'
    if (analysis['return1'] > analysis['return2'] and analysis['sharpe1'] > analysis['sharpe2']) or
       (analysis['return2'] > analysis['return1'] and analysis['sharpe2'] > analysis['sharpe1'])
    else '虽然该方案收益率较高，但风险也相对较大，建议密切关注市场变化。'}
    """

    with open('investment_strategy_report.txt', 'w', encoding='utf-8') as f:
        f.write(report)

    print("策略报告已生成: investment_strategy_report.txt")

    print("\n" + "=" * 60)
    print("投资策略设计完成！")
    print("结果文件:")
    print("  - asset_comparison.png: 资产变化对比图")
    print("  - price_trading_points.png: 价格走势与交易点图")
    print("  - trading_records.png: 交易记录表格")
    print("  - scheme1_transactions.csv: 方案1详细交易记录")
    print("  - scheme2_transactions.csv: 方案2详细交易记录")
    print("  - strategy_analysis.csv: 策略分析结果")
    print("  - investment_strategy_report.txt: 策略报告")
    print("=" * 60)


if __name__ == "__main__":
    main()